<?php

class StringUtil {

    /**
     * Return the real length of an UTF8 string
     *
     * @access public
     * @param string $utf8_string
     * @return int the number of utf8 characters in the string
     */
    public static function len($str, $is_utf8 = false) {
        if ($is_utf8) {
            return strlen(utf8_decode($str));
        } else {
            return strlen($str);
        }
    }

    /**
     * Escape an UTF8 string for display in an HTML page
     * Typically, will convert only the 'special fives'
     *    which are <,>,&,',"
     * Convert "\n" to "<br>"
     *
     * @access public
     * @param string $utf8_string
     * @return string the escaped string
     * @see Smarty modifier named utf8_escape_html
     */
    public static function escapeUTF8ToHTML($utf8_string) {
        return nl2br(htmlspecialchars($utf8_string, ENT_QUOTES, "UTF-8"));
    }

    /**
     * Escape an UTF8 string for display in an HTML textarea element
     * Typically, will convert only the 'special fives'
     *    which are <,>,&,',"
     *
     * @access public
     * @param string $utf8_string
     * @return string the escaped string
     * @see Smarty modifier named escapeUTF8ToHTML
     */
    public static function escapeUTF8ToTextarea($utf8_string) {
        return htmlspecialchars($utf8_string, ENT_QUOTES, "UTF-8");
    }

    /**
     * Escape an UTF8 string for use as JS litteral in HTML page
     * Typically, will convert only the 'special fives'
     *    which are <,>,&,'," (html parser escape)
     * after having added slashes in front of all ' and " and \
     * (javascript parser escape)
     *
     * @access public
     * @param string $utf8_string
     * @return string the escaped string
     * @see Smarty modifier named escapeUTF8ToDHTML
     */
    public static function escapeUTF8ToDHTML($utf8_string) {
        return htmlspecialchars(preg_replace("/\r?\n/", "\\n", str_replace("<", "\\x3C", addslashes($utf8_string))), ENT_QUOTES, "UTF-8");
    }

    /**
     * Escape an UTF8 string for use as JS litteral in JS script section
     * of an html page.
     * Will add slashes in front of all ' and " and \, then will escape
     * the opening tag characters '<' for avoiding problem with injected
     * closing </SCRIPT> tag.
     *
     * @access public
     * @param string $utf8_string
     * @return string the escaped string
     * @see Smarty modifier named escapeUTF8ToJS
     */
    public static function escapeUTF8ToJS($utf8_string) {
        return preg_replace("/\r?\n/", "\\n", str_replace("<", "\\x3C", addslashes($utf8_string)));
    }

    /**
     * Escape an UTF8 string for use as string in an XML document
     * The escaping is compatible for both text node and attributes
     * value.
     *
     * To fit with W3C recommandation on XML 1.0, we escape using UTF8 code
     * of the entity (and not the html entity). Only the recommanded characters
     * are escaped => &,",<,>,Carriage return and Line feed
     *
     * @param string $utf8_string
     * @return string the escaped string
     * @see Smarty modifier named escapeUTF8ToXML
     * @link http://www.w3.org/TR/2006/REC-xml-20060816/
     * @link http://www.w3.org/XML/Datamodel.html
     */
    public static function escapeUTF8ToXML($utf8_string) {
        return str_replace(array('&', '"', "'", '<', '>', "\r", "\n"), array('&#38;', '&#34;', '&#39;', '&#60;', '&#62;', '&#12;', '&#10;'), $utf8_string);
    }

    /**
     * Working utf8 substr function with no risks of cutting a >1 byte utf8 character
     * in half.
     *
     * To achieve that, regexp are used with curly brace repetition of an UTF8 char regexp,
     * it allows to read $from character, then capture $len character (max) in the second capture
     * group, then return the whole 2nd capture group.
     *
     * @param string $utf8_string
     * @param int $from the returned string will start at the start 'th position in string ,
     *   counting from zero. If $from is negative, the full string will be returned.
     * @param int $len If $len  is given and is positive, the string returned will contain at most $len
     *   characters beginning from start (depending on the length of string ). If string length is less than
     *   or equal to $from characters long, empty string will be returned. If $len is negative, the full string
     *   will be returned. If $len is 0 or false, it is considered infinite
     * @return string the subbed string
     * @see Smarty modifier named substrForUTF8
     * @link http://vn.php.net/substr
     */
    public static function substrForUTF8($utf8_string, $from, $len = 0) {
        $from = intval($from);
        $len = intval($len);
        $str_len = StringUtil::utf8_strlen($utf8_string);

        // treat $from parameter
        if ($from < 0) {
            $from += $str_len;
            if ($from < 0) {
                return '';
            }
        }
        // speed up the process in case the $from is too big
        elseif ($from >= $str_len) {
            return '';
        }


        // treat negative $len parameter
        if ($len < 0) {
            //speedup the process a little
            if ($from - $len >= $str_len) {
                return '';
            }

            $len += $str_len - $from;
        }


        return preg_replace('#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,' . $from . '}' .
                        '((?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+)' . (1 ? '{0,' . $len . '}' : '*') . ').*#s', '$1', $utf8_string);
    }

    public static function isEmpty($e) {
        if ($e == null || strlen($e) == 0 || trim($e) == "")
            return false;
        else
            return true;
    }

    public static function generateUniqueCode($number, $max_length, $prefix, $id) {
        $codes = array();
        $data_for_generate = array();
        $len_data_for_generate = array();
        $data_for_generate[0] = "qwertyuiopasdfghjklzxcvbnm";
        $data_for_generate[1] = "0123456789";
        $data_for_generate[2] = strtoupper($data_for_generate[0]);
        $len_data_for_generate[0] = strlen($data_for_generate[0]);
        $len_data_for_generate[1] = strlen($data_for_generate[1]);
        $len_data_for_generate[2] = strlen($data_for_generate[2]);

        for ($i = 0; $i < $number; $i++) {
            do {
                $code_generate = '';
                for ($j = 0; $j < $max_length; $j++) {
                    $code_type = rand(0, 2);
                    $strc = $data_for_generate[$code_type];
                    $index = rand(0, $len_data_for_generate[$code_type] - 1);
                    $code_generate .= $strc[$index];
                }
            } while (isset($codes[$prefix . $id . $code_generate]));

            $codes[$prefix . $id . $code_generate] = 1;
        }
        return array_keys($codes);
    }

    public static function isEmail($email) {
        return filter_var($email, FILTER_VALIDATE_EMAIL);
    }
}
